package com.ezregex;

/**
 * Created with IntelliJ IDEA.
 * User: ggargiulo
 * Date: 3/8/13
 * Time: 11:21 AM
 * To change this template use File | Settings | File Templates.
 */
public class RegexSegmentBuilder {

    private RegexSegmentBuilder() {

    }

    private static RegexSegmentTypeStep aNewRegexSegmentFor(String something) {
        return new Steps(something);
    }

    public static RegexCardinalityTypeStep aLiteral(String something) {
        return aNewRegexSegmentFor(something).ofType(SegmentType.LITERAL);
    }

    public static RegexCardinalityTypeStep aSequenceOf(String something) {
        return aNewRegexSegmentFor(something).ofType(SegmentType.SEQUENCE);
    }

    public static interface RegexSegmentTypeStep {
        RegexCardinalityTypeStep ofType(SegmentType segmentType);
    }

    public static interface RegexCardinalityTypeStep {

        RegexSegment withCardinality(int cardinality);

        RegexSegment withInfiniteCardinality();

        RegexSegment withIntervalCardinality(int from, int to);

    }

    public static class Steps implements RegexSegmentTypeStep, RegexCardinalityTypeStep {

        private int cardinality;

        private int cardinalityFromValue;

        private int cardinalityToValue;

        private CardinalityType cardinalityType;

        private SegmentType segmentType;

        private Steps(String something) {
            this.cardinality = 1;
            this.cardinalityType = CardinalityType.EXACTLY_ONCE;
            this.text = something;
        }

        @Override
        public RegexSegment withInfiniteCardinality() {
            this.cardinalityType = CardinalityType.AT_LEAST_ONCE;
            return this.build();
        }

        private String text;

        @Override
        public RegexSegment withCardinality(int cardinality) {
            if (cardinality == 1) {
                this.cardinalityType = CardinalityType.EXACTLY_ONCE;
            } else {
                this.cardinalityType = CardinalityType.NUMBER_OF_TIMES;
            }
            this.cardinality = cardinality;
            return this.build();
        }

        @Override
        public RegexSegment withIntervalCardinality(int from, int to) {
            this.cardinalityType = CardinalityType.INTERVAL;
            this.cardinalityFromValue = from;
            this.cardinalityToValue = to;
            return this.build();
        }

        @Override
        public RegexCardinalityTypeStep ofType(SegmentType segmentType) {
            this.segmentType = segmentType;
            return this;
        }

        private RegexSegment build() {
            return new RegexSegment(segmentType, cardinalityType, cardinality, cardinalityFromValue, cardinalityToValue, text);
        }

    }

}
